package com.school.admin.common.imit;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.school.admin.common.annotation.DataAuthority;
import com.school.admin.common.config.SystemConfig;
import com.school.admin.entity.MallSysPurview;
import com.school.admin.entity.MallSysPurviewRole;
import com.school.admin.service.MallSysPurviewRoleService;
import com.school.admin.service.MallSysPurviewService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @program: backstage-admin
 * @description:
 * @author: sunpx
 * @create: 2022-04-16 11:23
 **/
@SuppressWarnings("ALL")
@Component
@Slf4j
public class initAPI implements CommandLineRunner {

    @Autowired
    MallSysPurviewService mallSysPurviewService;

    @Autowired
    MallSysPurviewRoleService mallSysPurviewRoleService;
    @Autowired
    ApplicationContext applicationContext;

    @Override
    public void run(String... args) throws Exception {
        log.info("初始化接口信息开始");
        initApiInfo();
        log.info("初始化接口信息完成");
    }


    @Transactional
    public void initApiInfo() {
        RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = mapping.getHandlerMethods();
        Map<String, MallSysPurview> map = new HashMap<>();
        handlerMethods.forEach((key, value) -> {

            //获取地址值
            String address = value.toString();

            String replace = address.substring(0, address.indexOf("#"));

            //判断接口是否需要权限管理
            Class<?> cl1 = null;
            boolean isAdd=true;
            String name=null;
            try {
                cl1 = Class.forName(replace);

                Method[] methods = cl1.getMethods();
                for (Method method : methods) {
                    String substring = address.substring(address.indexOf("#") + 1, address.indexOf("("));
                    if (method.getName().equals(substring)) {
                        DataAuthority annotation = method.getAnnotation(DataAuthority.class);
                        ApiOperation api = method.getAnnotation(ApiOperation.class);
                        if (annotation!=null){
                            isAdd=annotation.isAuthorize();
                            name= annotation.name();
                        }
                        if (api!=null){
                            name=api.value();
                        }

                    }
                }

            } catch (ClassNotFoundException e) {
                isAdd=false;
            }

            String filterAddresses = SystemConfig.filterAddresses;
            boolean matches = Pattern.matches(filterAddresses,key.getPatternsCondition().getPatterns().toArray()[0].toString() );
            //判断是否需要纳入权限管理
            if (isAdd && !matches) {
                //初始化api
                MallSysPurview mallSysPurview = new MallSysPurview();
                //获取url
                String purviewUrl = key.getPatternsCondition().getPatterns().toArray()[0].toString();

                // 赋值
                mallSysPurview.setPurviewUrl(purviewUrl).setAddress(address).setPurviewName(name);
                //获取请求类型
                Set<RequestMethod> methods = key.getMethodsCondition().getMethods();
                if (!CollectionUtils.isEmpty(methods)) {
                    String method = methods.toArray()[0].toString();
                    mallSysPurview.setMethod(method);
                }

                map.put(purviewUrl,mallSysPurview);

            }
        });

        List<String> delIdList=new ArrayList<>();
        delIdList.add(null);
        List<MallSysPurview> list = mallSysPurviewService.list();
        for (MallSysPurview mallSysPurview : list) {
            MallSysPurview purviewVo = map.get(mallSysPurview.getPurviewUrl());
            if (purviewVo!=null) {
                //需要更新的接口信息
                purviewVo.setId(mallSysPurview.getId());
                continue;
            }
            //需要删除的接口信息
            delIdList.add(String.valueOf(mallSysPurview.getId()));
        }

        QueryWrapper<MallSysPurview> sysPurviewWrapper = new QueryWrapper<>();
        QueryWrapper<MallSysPurviewRole> sysPurviewRoleWrapper = new QueryWrapper<>();
        sysPurviewWrapper.in("id",delIdList);
        sysPurviewRoleWrapper.in("id",delIdList);
        //删除多余的接口数据
        mallSysPurviewService.remove(sysPurviewWrapper);
        //删除多余绑定的数据
        mallSysPurviewRoleService.remove(sysPurviewRoleWrapper);
        //保存更新接口数据
        mallSysPurviewService.saveOrUpdateBatch(map.values());

    }

}
